package com.zhiwei.msf.gateway.service.impl;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.zhiwei.msf.common.constant.DatabaseConstants;
import com.zhiwei.msf.common.constant.ResultResponseMsg;
import com.zhiwei.msf.common.exception.BasePublishException;
import com.zhiwei.msf.common.util.UuidUtil;
import com.zhiwei.msf.gateway.constants.GatewayErrorConstants;
import com.zhiwei.msf.gateway.dao.entity.UserInfo;
import com.zhiwei.msf.gateway.dto.UserRegisterDto;
import com.zhiwei.msf.gateway.service.CaptchaService;
import com.zhiwei.msf.gateway.service.LoginService;
import com.zhiwei.msf.gateway.service.UserInfoService;
import com.zhiwei.msf.gateway.service.UserTokenService;
import com.zhiwei.msf.gateway.util.JwtUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * function 用户登录服务
 * author zhiwei.yang
 * time 2020-2-27-16:59
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private UserInfoService userInfoService;

    @Override
    public ResultResponseMsg userLogin(String username, String password, String serialNo, String captcha) {
        if (!captchaService.matches(serialNo, captcha)) {
            throw new BasePublishException(GatewayErrorConstants.CAPTCHA_ERROR);
        }
        UserInfo userInfo = userInfoService.getUserInfoByName(username);
        if (null == userInfo) {
            throw new BasePublishException(GatewayErrorConstants.USER_NOT_EXIST);
        }
        if (!passwordEncoder.matches(password, userInfo.getPassword())) {
            throw new BasePublishException(GatewayErrorConstants.PASSWORD_INVALID);
        }
        String jwtToken = userTokenService.createToken(username);
        return ResultResponseMsg.buildSuccessResultMsg(jwtToken);
    }

    @Override
    public void userLogout(String token, String serialNo) {
        userTokenService.removeToken(token);
        captchaService.removeCaptcha(serialNo);
        Map<String, Object> tokenInfo = JwtUtil.parseJwtToken(token);
        String username = (String) tokenInfo.get(JwtUtil.NAME);
        log.info("用户【{}】退出登陆, token失效 ==> {}", username, token);
    }

    @Override
    public ResultResponseMsg userRegister(UserRegisterDto userRegisterDto, String serialNo) {
        if (StringUtils.isNotEmpty(userRegisterDto.getCaptcha()) && !captchaService.matches(serialNo, userRegisterDto.getCaptcha())) {
            throw new BasePublishException(GatewayErrorConstants.CAPTCHA_ERROR);
        }
        UserInfo userInfo = userInfoService.getUserInfoByName(userRegisterDto.getUsername());
        if (null != userInfo) {
            throw new BasePublishException(GatewayErrorConstants.USER_NAME_REPEAT);
        }
        UserInfo newUserInfo = new UserInfo();
        newUserInfo.setUuid(UuidUtil.getUUID());
        newUserInfo.setUsername(userRegisterDto.getUsername());
        newUserInfo.setPassword(passwordEncoder.encode(userRegisterDto.getPassword()));
        newUserInfo.setPhone(userRegisterDto.getPhone());
        newUserInfo.setEmail(userRegisterDto.getEmail());
        Date nowTime = new Date();
        newUserInfo.setCreateTime(nowTime);
        newUserInfo.setUpdateTime(nowTime);
        newUserInfo.setCreateUser(userRegisterDto.getUsername());
        newUserInfo.setUpdateUser(userRegisterDto.getUsername());
        newUserInfo.setEnableFlag(DatabaseConstants.ENABLE);
        if (userInfoService.addUser(newUserInfo)) {
            String token = userTokenService.createToken(userRegisterDto.getUsername());
            log.info("用户注册成功信息userRegisterDto：{}, Token:{}", JSONObject.toJSONString(userRegisterDto), token);
            return ResultResponseMsg.buildSuccessResultMsg(token);
        }
        log.info("用户注册信息失败userRegisterDto：{}", JSONObject.toJSONString(userRegisterDto));
        return ResultResponseMsg.buildFailureResultMsg();
    }
}